package com.daniel.juc.lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 生产者消费者Synchronized
 * 线程之间的通信问题：等待唤醒，通知唤醒
 * 线程交替执行 A B 操作同一个变量 num=0
 * A num+1
 * B num-1
 *
 * @author Daniel
 * @version V1.0
 * @date 2020/5/18 11:05
 */
public class PcDemo02 {
	public static void main(String[] args) {
		Data2 data = new Data2();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				data.increment();
			}
		}, "A").start();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				data.decrement();
			}
		}, "B").start();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				data.increment();
			}
		}, "C").start();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				data.decrement();
			}
		}, "D").start();
	}

}

/**
 * 判断等待，业务，通知
 * 数字资源类
 */
class Data2 {
	private int number = 0;

	Lock lock = new ReentrantLock();
	// condition.await() //等待
	// condition.signalAll() //唤醒全部
	Condition condition = lock.newCondition();

	/**
	 * +1操作
	 */
	public void increment() {
		lock.lock();
		try {
			while (number != 0) {
				// 等待
				condition.await();
			}

			number++;
			System.out.println(Thread.currentThread().getName() + "=>" + number);
			// 通知其他线程，我+1完毕了
			condition.signalAll();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}

	}

	/**
	 * -1操作
	 */
	public void decrement() {
		lock.lock();
		try {
			while (number == 0) {
				// 等待
				condition.await();
			}
			number--;
			System.out.println(Thread.currentThread().getName() + "=>" + number);
			// 通知其他线程，我-1完毕了
			condition.signalAll();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}
